<!--&lt;!&ndash;<!DOCTYPE html>&ndash;&gt;-->
<!--&lt;!&ndash;<html>&ndash;&gt;-->
<!--&lt;!&ndash;<head>&ndash;&gt;-->
<!--&lt;!&ndash;    <meta charset="utf-8" />&ndash;&gt;-->
<!--&lt;!&ndash;    <title></title>&ndash;&gt;-->
<!--&lt;!&ndash;    <style>&ndash;&gt;-->
<!--&lt;!&ndash;        #cvs {&ndash;&gt;-->
<!--&lt;!&ndash;            border: 2px solid pink;&ndash;&gt;-->
<!--&lt;!&ndash;        }&ndash;&gt;-->
<!--&lt;!&ndash;    </style>&ndash;&gt;-->
<!--&lt;!&ndash;    <script>&ndash;&gt;-->
<!--&lt;!&ndash;        addEventListener("DOMContentLoaded", function () {&ndash;&gt;-->
<!--&lt;!&ndash;            var cvs = document.getElementById("cvs");&ndash;&gt;-->
<!--&lt;!&ndash;            var cxt = cvs.getContext("2d");&ndash;&gt;-->
<!--&lt;!&ndash;            var pointSize = 6;&ndash;&gt;-->
<!--&lt;!&ndash;            cxt.fillStyle = "rgba(0,0,0,1)";&ndash;&gt;-->
<!--&lt;!&ndash;            cxt.fillRect(0, 0, cvs.width, cvs.height);&ndash;&gt;-->
<!--&lt;!&ndash;            cxt.fillStyle = "rgba(77,153,204,1)";&ndash;&gt;-->
<!--&lt;!&ndash;            cxt.fillRect((cvs.width - pointSize) / 2, (cvs.height - pointSize) / 2, pointSize, pointSize);&ndash;&gt;-->
<!--&lt;!&ndash;        });&ndash;&gt;-->
<!--&lt;!&ndash;    </script>&ndash;&gt;-->
<!--&lt;!&ndash;</head>&ndash;&gt;-->
<!--&lt;!&ndash;<body>&ndash;&gt;-->
<!--&lt;!&ndash;<canvas id="cvs" width="800" height="600"></canvas>&ndash;&gt;-->
<!--&lt;!&ndash;</body>&ndash;&gt;-->
<!--&lt;!&ndash;</html>&ndash;&gt;-->

<!--&lt;!&ndash;<!DOCTYPE html>&ndash;&gt;-->
<!--&lt;!&ndash;<html>&ndash;&gt;-->
<!--&lt;!&ndash;<head>&ndash;&gt;-->
<!--&lt;!&ndash;    <meta charset="utf-8" />&ndash;&gt;-->
<!--&lt;!&ndash;    <title></title>&ndash;&gt;-->
<!--&lt;!&ndash;    <style>&ndash;&gt;-->
<!--&lt;!&ndash;        #threejs {&ndash;&gt;-->
<!--&lt;!&ndash;            border: 2px solid pink;&ndash;&gt;-->
<!--&lt;!&ndash;            width:800px;&ndash;&gt;-->
<!--&lt;!&ndash;            height:600px;&ndash;&gt;-->
<!--&lt;!&ndash;        }&ndash;&gt;-->
<!--&lt;!&ndash;    </style>&ndash;&gt;-->
<!--&lt;!&ndash;    <script src="./three.js"></script>&ndash;&gt;-->
<!--&lt;!&ndash;    <script>&ndash;&gt;-->
<!--&lt;!&ndash;        addEventListener("DOMContentLoaded", function () {&ndash;&gt;-->
<!--&lt;!&ndash;            var threejs = document.getElementById("threejs");&ndash;&gt;-->
<!--&lt;!&ndash;            //点的尺寸&ndash;&gt;-->
<!--&lt;!&ndash;            var size = 6;&ndash;&gt;-->
<!--&lt;!&ndash;            var width = 800, height = 600;&ndash;&gt;-->
<!--&lt;!&ndash;            //新建场景&ndash;&gt;-->
<!--&lt;!&ndash;            var scene = new THREE.Scene();&ndash;&gt;-->
<!--&lt;!&ndash;            //新建正射投影摄像机，摄像机的可视截面宽为width,高为height,近截面距离为0.1，远截面为1&ndash;&gt;-->
<!--&lt;!&ndash;            var camera = new THREE.OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, 0.1, 1);&ndash;&gt;-->
<!--&lt;!&ndash;            //摄像机往z轴移1，才能看到物体&ndash;&gt;-->
<!--&lt;!&ndash;            camera.position.z = 1;&ndash;&gt;-->
<!--&lt;!&ndash;            //新建渲染器&ndash;&gt;-->
<!--&lt;!&ndash;            var renderer = new THREE.WebGLRenderer();&ndash;&gt;-->
<!--&lt;!&ndash;            //设置渲染视口大小，你可以改成400,300试试&ndash;&gt;-->
<!--&lt;!&ndash;            renderer.setSize(width, height);&ndash;&gt;-->
<!--&lt;!&ndash;            //添加画布到文档中&ndash;&gt;-->
<!--&lt;!&ndash;            threejs.appendChild(renderer.domElement);&ndash;&gt;-->
<!--&lt;!&ndash;            //新建平面几何结构，宽高都为6&ndash;&gt;-->
<!--&lt;!&ndash;            var geometry = new THREE.PlaneGeometry(size, size);&ndash;&gt;-->
<!--&lt;!&ndash;            //新建材质，颜色为蓝色&ndash;&gt;-->
<!--&lt;!&ndash;            var material = new THREE.MeshBasicMaterial({ color: 0x4d99cc });&ndash;&gt;-->
<!--&lt;!&ndash;            //结合物体的结构和材质&ndash;&gt;-->
<!--&lt;!&ndash;            var plane = new THREE.Mesh(geometry, material);&ndash;&gt;-->
<!--&lt;!&ndash;            //添加到场景里才能被渲染&ndash;&gt;-->
<!--&lt;!&ndash;            scene.add(plane);&ndash;&gt;-->
<!--&lt;!&ndash;            //开始使用给定的摄像机渲染给定的场景&ndash;&gt;-->
<!--&lt;!&ndash;            renderer.render(scene, camera);&ndash;&gt;-->
<!--&lt;!&ndash;        });&ndash;&gt;-->
<!--&lt;!&ndash;    </script>&ndash;&gt;-->
<!--&lt;!&ndash;</head>&ndash;&gt;-->
<!--&lt;!&ndash;<body>&ndash;&gt;-->
<!--&lt;!&ndash;<div id="threejs"></div>&ndash;&gt;-->
<!--&lt;!&ndash;</body>&ndash;&gt;-->
<!--&lt;!&ndash;</html>&ndash;&gt;-->

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title></title>
    <style>
        #webgl {
            border: 2px solid pink;
            width:800px;
            height:600px;
            margin: 0 auto;
            display: block;
        }
    </style>


    <script src="./lib.js"></script>

    <script id="vertexShader" type="x-shader/x-vertex">
            //这部分是顶点着色器
            //声明一个attribute类型的4维向量a_Position
          attribute vec3 a_Position;
          attribute vec4 a_Color;
          attribute vec2 a_TextCoord;
          attribute vec3 a_Normal;
          varying vec4 v_Color;
          varying vec2 v_TextCoord;
          varying vec3 v_FragPosition;
           varying vec3 v_Normal;
          uniform mat4 u_mat;
          uniform mat4 u_modelMatrix;
          uniform mat4 u_viewMatrix;
          uniform mat4 u_projMatrix;
          void main() {
              gl_Position = u_projMatrix * u_viewMatrix * u_modelMatrix * vec4(a_Position,1.0);
              v_FragPosition = vec3(u_modelMatrix * vec4(a_Position,1.0));
              v_Color = a_Color;
              //v_TextCoord = a_TextCoord;
              v_Normal = mat3(u_modelMatrix) * a_Normal;
          }

    </script>
    <script id="fragmentShader" type="x-shader/x-fragment">
          precision  mediump float;
          //varying vec2 v_TextCoord;
          varying vec4 v_Color;
          varying vec3 v_FragPosition;
          varying vec3 v_Normal;
          uniform sampler2D u_Sampler0;
          uniform sampler2D u_Sampler1;

          uniform vec3 u_LightColor;
          uniform vec3 u_LightPosition;
          uniform vec3 u_AmbientColor;
          uniform vec3 u_CameraPos;

          void main() {
            //gl_FragColor = v_Color * texture2D(u_Sampler0, v_TextCoord) * texture2D(u_Sampler1, v_TextCoord);
            vec3 lightDir = normalize(u_LightPosition - v_FragPosition);
            vec3 reflectVec = reflect(-lightDir ,v_Normal);
            vec3 cameraVec = normalize(u_CameraPos - v_FragPosition);
            float specularAmount = pow(max(dot(reflectVec,cameraVec),0.0),128.0) * 0.5;
            vec3 specular = specularAmount * u_LightColor;
            float nDotL =  max(dot(v_Normal,u_LightPosition),0.0);
            vec3 ambient = u_AmbientColor;
            vec3 diffuse =  u_LightColor * nDotL;

            gl_FragColor = vec4(( diffuse + ambient + specular ) * v_Color.rgb,1.0);
          }

    </script>

    <script>

      // var arr1 = [0.5, 0.5, 0]
      // var arr2 = [1, 0, 0]
      // console.log(Math.sqrt(0.5 * 0.5 + 0.5 * 0.5) * Math.sqrt(1) *  Math.cos(45 / 180 * Math.PI))
      // console.log(arr1[0] * arr2[0] + arr1[1] * arr2[1])

      function normalize(v) {
        var c = v[0], d = v[1], e = v[2], g = Math.sqrt(c * c + d * d + e * e)
        if (g) {
          if (g == 1)
            return v
        } else {
          v[0] = 0
          v[1] = 0
          v[2] = 0
          return v
        }
        g = 1 / g
        v[0] = c * g
        v[1] = d * g
        v[2] = e * g
        return v
      }


      function cross(v, w) {
        var arr = [0, 0, 0]
        arr[0] = v[1] * w[2] - v[2] * w[1]
        arr[1] = v[2] * w[0] - v[0] * w[2]
        arr[2] = v[0] * w[1] - v[1] * w[0]

        return arr

      }


      window.onload = async function () {

        //顶点着色器程序
        var VSHADER_SOURCE = document.getElementById("vertexShader").text

        //片元着色器
        var FSHADER_SOURCE = document.getElementById("fragmentShader").text

        //获取canvas元素
        var canvas = document.getElementById('webgl')
        //获取绘制二维上下文
        var gl = canvas.getContext('webgl')

        //编译着色器
        var vertShader = gl.createShader(gl.VERTEX_SHADER)
        gl.shaderSource(vertShader, VSHADER_SOURCE)
        gl.compileShader(vertShader)

        var fragShader = gl.createShader(gl.FRAGMENT_SHADER)
        gl.shaderSource(fragShader, FSHADER_SOURCE)
        gl.compileShader(fragShader)
        //合并程序
        var shaderProgram = gl.createProgram()
        gl.attachShader(shaderProgram, vertShader)
        gl.attachShader(shaderProgram, fragShader)
        gl.linkProgram(shaderProgram)
        gl.useProgram(shaderProgram)

        // gl.enable(gl.CULL_FACE)
        // gl.cullFace(gl.FRONT)
        gl.enable(gl.DEPTH_TEST)

        var n = initBuffers(gl, shaderProgram)

        gl.clearColor(0.2, 0.3, 0.3, 1.0)

        {
          const {texture, u_Sampler, image} = await initTexture("./awesomeface.png", gl, shaderProgram, 0)
          await loadTexture(gl, n, texture, u_Sampler, image, 0)
        }


        {
          const {texture, u_Sampler, image} = await initTexture("./container.png", gl, shaderProgram, 1)
          await loadTexture(gl, n, texture, u_Sampler, image, 1)
        }

        var _angle = 0
        var u_mat = gl.getUniformLocation(shaderProgram, 'u_mat')
        var u_modelMatrix = gl.getUniformLocation(shaderProgram, 'u_modelMatrix')
        var u_viewMatrix = gl.getUniformLocation(shaderProgram, 'u_viewMatrix')
        var u_projMatrix = gl.getUniformLocation(shaderProgram, 'u_projMatrix')
        var u_CameraPos = gl.getUniformLocation(shaderProgram, 'u_CameraPos')

        var fov = 45

        var projMatrix = new Matrix4()
        projMatrix = projMatrix.setPerspective(fov, 800 / 600, 0.1, 100.0)

        var cameraPos = [0, 0, 3.0]
        var cameraFront = [0, 0, -1.0]
        var cameraUp = [0, 1, 0]
        var cameraSpeed = 0.2

        var cubePositions = [
          0.0, 0.0, 0.0,
          2.0, 5.0, -15.0,
          -1.5, -2.2, -2.5,
          -3.8, -2.0, -12.3,
          2.4, -0.4, -3.5,
          -1.7, 3.0, -7.5,
          1.3, -2.0, -2.5,
          1.5, 2.0, -2.5,
          1.5, 0.2, -1.5,
          -1.3, 1.0, -1.5
        ]

        render()

        document.onkeydown = function (e) {
          /***
           * 87,83,68,65 上下左右
           */
          if (e.keyCode === 68 || e.keyCode === 65 || e.keyCode === 87 || e.keyCode === 83 || e.keyCode === 69 || e.keyCode === 81) {
            if (e.keyCode === 87) {
              cameraPos[0] += cameraSpeed * cameraFront[0]
              cameraPos[1] += cameraSpeed * cameraFront[1]
              cameraPos[2] += cameraSpeed * cameraFront[2]
            } else if (e.keyCode === 83) {
              cameraPos[0] -= cameraSpeed * cameraFront[0]
              cameraPos[1] -= cameraSpeed * cameraFront[1]
              cameraPos[2] -= cameraSpeed * cameraFront[2]
            } else if (e.keyCode === 68) {
              cameraPos[0] += cameraSpeed * normalize(cross(cameraFront, cameraUp))[0]
              cameraPos[1] += cameraSpeed * normalize(cross(cameraFront, cameraUp))[1]
              cameraPos[2] += cameraSpeed * normalize(cross(cameraFront, cameraUp))[2]
            } else if (e.keyCode === 65) {
              cameraPos[0] -= cameraSpeed * normalize(cross(cameraFront, cameraUp))[0]
              cameraPos[1] -= cameraSpeed * normalize(cross(cameraFront, cameraUp))[1]
              cameraPos[2] -= cameraSpeed * normalize(cross(cameraFront, cameraUp))[2]
            }else if (e.keyCode === 81) {
              cameraPos[0] -= cameraSpeed * cameraUp[0]
              cameraPos[1] -= cameraSpeed * cameraUp[1]
              cameraPos[2] -= cameraSpeed * cameraUp[2]
            }else if (e.keyCode === 69) {
              cameraPos[0] += cameraSpeed * cameraUp[0]
              cameraPos[1] += cameraSpeed * cameraUp[1]
              cameraPos[2] += cameraSpeed * cameraUp[2]
            }
          }
        }

        // Yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction vector pointing
        // to the right (due to how Eular angles work) so we initially rotate a bit to the left.
        var yaw = -90.0
        var pitch = 0.0
        var lastX = 400, lastY = 300
        var sensitivity = 0.2
        var firstMouse = true
        document.onmousemove = function (e) {
          var xpos = e.x
          var ypos = e.y

          if (firstMouse) {
            lastX = xpos
            lastY = ypos
            firstMouse = false
          }

          var xoffset = xpos - lastX
          var yoffset = lastY - ypos // 注意这里是相反的，因为y坐标的范围是从下往上的
          lastX = xpos
          lastY = ypos

          xoffset *= sensitivity
          yoffset *= sensitivity
          yaw += xoffset
          pitch += yoffset
          if (pitch > 89.0)
            pitch = 89.0
          if (pitch < -89.0)
            pitch = -89.0

          var front = [0, 0, 0]
          front[0] = Math.cos(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI)
          front[1] = Math.sin(pitch / 180 * Math.PI)
          front[2] = Math.sin(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI)
          cameraFront = normalize(front)
        }

        document.onwheel = function (e) {
          if (e.wheelDelta > 0) {
            cameraPos[0] += cameraSpeed * 10 * cameraFront[0]
            cameraPos[1] += cameraSpeed * 10 * cameraFront[1]
            cameraPos[2] += cameraSpeed * 10 * cameraFront[2]
          } else {
            cameraPos[0] -= cameraSpeed * 10 * cameraFront[0]
            cameraPos[1] -= cameraSpeed * 10 * cameraFront[1]
            cameraPos[2] -= cameraSpeed * 10 * cameraFront[2]
          }
        }


        function render() {
          var angle = _angle % 360
          _angle += 0.02
          // modleMatrix.setRotate(angle, 0, 0, 1)

          // var radian = Math.PI * angle / 180.0
          //
          // var sin = Math.sin(radian)
          // var cos = Math.cos(radian)
          //
          // var haha = new Float32Array([
          //   cos, sin, 0.0, 0.0,
          //   -sin, cos, 0.0, 0.0,
          //   0.0, 0.0, 1.0, 0.0,
          //   0.0, 0.0, 0.0, 1.0
          // ])
          //
          // gl.uniformMatrix4fv(u_mat, false, haha)

          // 清除指定<画布>的颜色
          gl.clearColor(0.1, 0.1, 0.1, 1.0)

          // 清空 <canvas>
          gl.clear(gl.COLOR_BUFFER_BIT)
          gl.clear(gl.DEPTH_BUFFER_BIT)

          // var radius = 10.0
          // const camX = Math.sin(angle) * radius
          // const camZ = Math.cos(angle) * radius

          var viewMatrix = new Matrix4()

          viewMatrix = viewMatrix.lookAt(
            cameraPos[0],
            cameraPos[1],
            cameraPos[2],
            cameraPos[0] + cameraFront[0],
            cameraPos[1] + cameraFront[1],
            cameraPos[2] + cameraFront[2],
            cameraUp[0],
            cameraUp[1],
            cameraUp[2])
          // viewMatrix = viewMatrix.lookAt(camX, 0, camZ, 0, 0, 0, 0, 1, 0)

          gl.uniformMatrix4fv(u_viewMatrix, false, viewMatrix.elements)
          gl.uniformMatrix4fv(u_projMatrix, false, projMatrix.elements)
          gl.uniform3f(u_CameraPos, cameraPos[0], cameraPos[1],cameraPos[2])

          for (var i = 0; i < 30; i += 3) {

            var modleMatrix = new Matrix4()
            modleMatrix.translate(cubePositions[i], cubePositions[i + 1], cubePositions[i + 2])
            // modleMatrix.rotate(20.0 * i / 3, 1.0, 0.3, 0.5)

            gl.uniformMatrix4fv(u_modelMatrix, false, modleMatrix.elements)

            gl.drawArrays(gl.TRIANGLES, 0, n)
          }
          //
          // var modleMatrix = new Matrix4()
          // gl.uniformMatrix4fv(u_modelMatrix, false, modleMatrix.elements)
          //
          // gl.drawArrays(gl.TRIANGLES, 0, n)

          // gl.drawArrays(gl.TRIANGLES, 0, n)
          // gl.drawArrays(gl.TRIANGLE_STRIP, 0, n)
          // gl.drawElements(gl.TRIANGLES, 6,gl.UNSIGNED_SHORT,0)
          requestAnimationFrame(render)
        }

      }

      function initBuffers(gl, shaderProgram) {
        // var vertices = new Float32Array([
        //     0.0, 0.5, 1.0, 0.0, 0.0,
        //     -0.5, -0.5, 0.0, 1.0, 0.0,
        //     0.5, -0.5, 0.0, 0.0, 1.0,
        // ])

        var vertices = new Float32Array([
          -0.5, -0.5, -0.5, 0.0, 0.0, -1.0,
          0.5, -0.5, -0.5, 0.0, 0.0, -1.0,
          0.5, 0.5, -0.5, 0.0, 0.0, -1.0,
          0.5, 0.5, -0.5, 0.0, 0.0, -1.0,
          -0.5, 0.5, -0.5, 0.0, 0.0, -1.0,
          -0.5, -0.5, -0.5, 0.0, 0.0, -1.0,

          -0.5, -0.5, 0.5, 0.0, 0.0, 1.0,
          0.5, -0.5, 0.5, 0.0, 0.0, 1.0,
          0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
          0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
          -0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
          -0.5, -0.5, 0.5, 0.0, 0.0, 1.0,

          -0.5, 0.5, 0.5, -1.0, 0.0, 0.0,
          -0.5, 0.5, -0.5, -1.0, 0.0, 0.0,
          -0.5, -0.5, -0.5, -1.0, 0.0, 0.0,
          -0.5, -0.5, -0.5, -1.0, 0.0, 0.0,
          -0.5, -0.5, 0.5, -1.0, 0.0, 0.0,
          -0.5, 0.5, 0.5, -1.0, 0.0, 0.0,

          0.5, 0.5, 0.5, 1.0, 0.0, 0.0,
          0.5, 0.5, -0.5, 1.0, 0.0, 0.0,
          0.5, -0.5, -0.5, 1.0, 0.0, 0.0,
          0.5, -0.5, -0.5, 1.0, 0.0, 0.0,
          0.5, -0.5, 0.5, 1.0, 0.0, 0.0,
          0.5, 0.5, 0.5, 1.0, 0.0, 0.0,

          -0.5, -0.5, -0.5, 0.0, -1.0, 0.0,
          0.5, -0.5, -0.5, 0.0, -1.0, 0.0,
          0.5, -0.5, 0.5, 0.0, -1.0, 0.0,
          0.5, -0.5, 0.5, 0.0, -1.0, 0.0,
          -0.5, -0.5, 0.5, 0.0, -1.0, 0.0,
          -0.5, -0.5, -0.5, 0.0, -1.0, 0.0,

          -0.5, 0.5, -0.5, 0.0, 1.0, 0.0,
          0.5, 0.5, -0.5, 0.0, 1.0, 0.0,
          0.5, 0.5, 0.5, 0.0, 1.0, 0.0,
          0.5, 0.5, 0.5, 0.0, 1.0, 0.0,
          -0.5, 0.5, 0.5, 0.0, 1.0, 0.0,
          -0.5, 0.5, -0.5, 0.0, 1.0, 0.0
        ])

        // var indices = new Uint16Array([
        //     0, 1, 2, 3, 1, 2
        // ])

        var n = 36//点的个数
        //创建缓冲区对象
        var vertexBuffer = gl.createBuffer()

        //将缓冲区对象绑定到目标
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
        //向缓冲区写入数据
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        // var elementBuffer = gl.createBuffer()

        // //将缓冲区对象绑定到目标
        // gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer)
        // //向缓冲区写入数据
        // gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)

        //获取坐标点
        var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position')
        var a_Color = gl.getAttribLocation(shaderProgram, 'a_Color')
        var a_TextCoord = gl.getAttribLocation(shaderProgram, 'a_TextCoord')
        var a_Normal = gl.getAttribLocation(shaderProgram, 'a_Normal')
        var u_LightColor = gl.getUniformLocation(shaderProgram, 'u_LightColor')
        var u_LightPosition = gl.getUniformLocation(shaderProgram, 'u_LightPosition')
        var u_AmbientColor = gl.getUniformLocation(shaderProgram, 'u_AmbientColor')

        gl.vertexAttrib4f(a_Color, 1.0, 0.5, 0.31, 1.0)
        gl.uniform3f(u_AmbientColor, 0.2, 0.1,0.0)
        gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0)
        var lightPosition = new Vector3([10.0, 10.0, -5.0])
        gl.uniform3fv(u_LightPosition, lightPosition.normalize().elements)

        var size = vertices.BYTES_PER_ELEMENT
        //将缓冲区对象分配给a_Position变量
        gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 6 * size, 0)
        gl.vertexAttribPointer(a_Normal, 3, gl.FLOAT, false, 6 * size, 3 * size)
        // gl.vertexAttribPointer(a_TextCoord, 2, gl.FLOAT, false, 5 * size, 3 * size)
        // gl.vertexAttribPointer(a_Color, 4, gl.FLOAT, false, 8 * size, 4 * size)
        //连接a_Position变量与分配给它的缓冲区对象
        gl.enableVertexAttribArray(a_Position)
        gl.enableVertexAttribArray(a_Normal)
        gl.enableVertexAttribArray(a_TextCoord)
        // gl.enableVertexAttribArray(a_Color)
        return n

      }

      function initTexture(src, gl, shaderProgram, n) {
        return new Promise((resolve, reject) => {
          //创建纹理对象
          var texture = gl.createTexture()
          //获取u_Sampler的存储位置
          var u_Sampler = gl.getUniformLocation(shaderProgram, `u_Sampler${n}`)

          //创建image对象
          var image = new Image()

          //加载纹理
          image.onload = function () {
            resolve({image, texture, u_Sampler})
          }
          // 浏览器开始加载图片 注意：一定是2^mx2^n尺寸的图片
          image.src = src
        })
      }

      function loadTexture(gl, n, texture, u_Sampler, image, pos) {

        //1.对纹理图像进行Y轴反转
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1)
        //2.开启0号纹理单元
        gl.activeTexture(gl[`TEXTURE${pos}`])
        //3.向target绑定纹理对象
        gl.bindTexture(gl.TEXTURE_2D, texture)

        //4.配置纹理参数
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
        //5.配置纹理图像
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image)

        //6.将0号纹理图像传递给着色器
        gl.uniform1i(u_Sampler, pos)
      }

    </script>
</head>
<body>
<canvas id="webgl" width="800" height="600"></canvas>
</body>
</html>
